package com.polaris.live.ui.party.fragment.video

import android.app.Activity
import android.os.Build
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.lifecycle.lifecycleScope
import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.ScreenUtils
import com.blankj.utilcode.util.Utils
import com.bumptech.glide.Glide
import com.gyf.immersionbar.ImmersionBar
import com.lxj.xpopup.XPopup
import com.polaris.live.R.drawable
import com.polaris.live.cache.CommonCache
import com.polaris.live.common.cacha.UserManager
import com.polaris.live.common.constant.PagConst
import com.polaris.live.common.ext.autoDp
import com.polaris.live.common.ext.dp
import com.polaris.live.common.ext.formatNumberWithK
import com.polaris.live.common.ext.setOnSingleClickListener
import com.polaris.live.common.network.parseState
import com.polaris.live.common.util.JsonUtils
import com.polaris.live.common.util.NavigationBarUtils
import com.polaris.live.common.util.ToastGravity
import com.polaris.live.common.util.ViewUtils
import com.polaris.live.constant.LiveConst
import com.polaris.live.constant.UserConst
import com.polaris.live.databinding.FragmentPartyVideoAnchorBinding
import com.polaris.live.dialog.AwardProgressDialog
import com.polaris.live.dialog.GlobalDialogManager
import com.polaris.live.dialog.LiveHangUpDialog
import com.polaris.live.dialog_fragment.MusicPopup
import com.polaris.live.dialog_fragment.RoomInvitationFragmentDialog
import com.polaris.live.dialog_fragment.magiclamp.MagicLampPopup
import com.polaris.live.im.manager.ImLiveManager
import com.polaris.live.im.manager.RouterControlManager
import com.polaris.live.im.sfs.BIG_BROTHER_ENTERS_ROOM
import com.polaris.live.im.sfs.LIVE_MAGIC_LAMP_90
import com.polaris.live.im.sfs.LIVE_MAGIC_LAMP_OPEN
import com.polaris.live.im.sfs.LIVE_NEW_ANCHOR
import com.polaris.live.im.sfs.LIVE_PARTY_EMOJI
import com.polaris.live.im.sfs.LIVE_PUBLIC_SCREEN
import com.polaris.live.im.sfs.LIVE_SEND_GIFT
import com.polaris.live.im.sfs.LIVE_WARN_MESSAGE
import com.polaris.live.im.sfs.LUCKY_BACKPACK_GIFT
import com.polaris.live.im.sfs.bean.live.LivePublicScreenMessage
import com.polaris.live.im.sfs.bean.live.LiveRoomInfo
import com.polaris.live.im.sfs.bean.live.SendLiveCloseMessage
import com.polaris.live.im.sfs.bean.live.SendLiveFloatingMessage
import com.polaris.live.im.sfs.bean.live.SendLiveMessage
import com.polaris.live.im.sfs.bean.live.SendLiveNoticeMessage
import com.polaris.live.im.sfs.bean.live.ext.LiveEnterBean
import com.polaris.live.im.sfs.bean.live.ext.MessageUserExtBean
import com.polaris.live.im.sfs.bean.live.ext.UserBasicVo
import com.polaris.live.im.sfs.bean.live.payload.InviteGiftPayloadBean
import com.polaris.live.im.sfs.bean.live.payload.LiveNoticePayloadBean
import com.polaris.live.im.sfs.bean.live.payload.NewAnchorSubsidyPayloadBean
import com.polaris.live.im.sfs.core.bean.DataArgument
import com.polaris.live.im.utils.SmartFoxUtils.parseVariables
import com.polaris.live.manager.AppConfigManager
import com.polaris.live.popup.BeautyPopup
import com.polaris.live.popup.ContributionListPopup
import com.polaris.live.popup.GameListPopup
import com.polaris.live.popup.GlobalPopupManager
import com.polaris.live.popup.MagicLampWinRewardPopup
import com.polaris.live.popup.VipBarrageWhatPopup
import com.polaris.live.popup.party.InteractionEmojiPopup
import com.polaris.live.popup.party.RoomInfoAnchorPopup
import com.polaris.live.popup.party.RoomManagementPopup
import com.polaris.live.popup.party.SeatSettingPopup
import com.polaris.live.popup.party.UnLockSeatPopup
import com.polaris.live.resp.back_resp.InfoOtherResp
import com.polaris.live.resp.back_resp.LiveEmojiResp
import com.polaris.live.resp.back_resp.LiveSubsidyIndicatorResp
import com.polaris.live.resp.back_resp.ScreenshotStrategyVo
import com.polaris.live.resp.back_resp.toUserBasicVo
import com.polaris.live.resp.bean.MagicLampCountDownBean
import com.polaris.live.resp.event.BackgroundEvent
import com.polaris.live.translation.R
import com.polaris.live.ui.game.GameUtils
import com.polaris.live.ui.live.proxy.LivePublicProxy
import com.polaris.live.ui.live.proxy.gift.EntryScreenAnimationProxy
import com.polaris.live.ui.live.proxy.gift.GiftAnimationProxy
import com.polaris.live.ui.live.widget.LiveFloatView
import com.polaris.live.ui.live.widget.listener.OnBackPressedListener
import com.polaris.live.ui.live.widget.listener.OnLiveNetworkListener
import com.polaris.live.ui.live.widget.listener.OnSendPartyMessageListener
import com.polaris.live.ui.message.fragment.MessageSessionFragment
import com.polaris.live.ui.message.fragment.dialog.MessageSessionDialogFragment
import com.polaris.live.ui.message.fragment.dialog.MessageSingleDialogFragment
import com.polaris.live.ui.party.fragment.base.BasePartyFragment
import com.polaris.live.ui.party.listener.OnRoomFinishCallback
import com.polaris.live.ui.party.listener.PartyImListener
import com.polaris.live.ui.party.utils.BigBrotherEntersTheArenaProxy
import com.polaris.live.ui.party.utils.GiftDialogProxy
import com.polaris.live.ui.party.utils.GiftGivingAnimationProxy
import com.polaris.live.ui.party.utils.PartyImProxy
import com.polaris.live.ui.party.widget.PartyBottomView
import com.polaris.live.ui.party.widget.seat.SeatBeanUtil
import com.polaris.live.ui.party.widget.seat.bean.BaseSeatBean
import com.polaris.live.ui.party.widget.videoseat.bean.VideoSeatBean
import com.polaris.live.ui.party.widget.videoseat.listener.PartyVideoSeatListener
import com.polaris.live.utils.LiveUtils
import com.polaris.live.utils.StartLiveProxy
import com.polaris.live.utils.TaskRedListener
import com.polaris.live.utils.TaskRedProxy
import com.polaris.live.utils.XPopupUtils
import com.polaris.live.utils.autoFragmentHide
import com.polaris.live.utils.file.FileUtils
import com.polaris.live.utils.fragment.showNewDialogFragment
import com.polaris.live.utils.image.ImageUtils
import com.polaris.live.utils.route.RoutePath
import com.polaris.live.utils.route.Router
import com.polaris.live.utils.zego.beauty.FaceManager
import com.polaris.live.utils.zego.media.MediaProxy
import com.polaris.live.viewmodel.party.PartyAnchorFragmentModel
import com.polaris.live.widget.bubble.DownLoadFileUtil
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.libpag.PAGFile
import org.libpag.PAGScaleMode
import sfs2x.client.core.SFSEvent
import sfs2x.client.entities.variables.RoomVariable
import java.io.File

/**
 * PartyVideoAnchorFragment
 *
 * @author Created by 天晴 on 2024/6/21 9:29
 * @since 1.0.0
 **/
class PartyVideoAnchorFragment : BasePartyFragment<PartyAnchorFragmentModel, FragmentPartyVideoAnchorBinding>(),
    OnLiveNetworkListener, OnBackPressedListener {

    private val mLiveInfo by lazy {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            arguments?.getParcelable(LiveConst.Params.LIVE_INFO, LiveRoomInfo::class.java)
        } else {
            arguments?.getParcelable(LiveConst.Params.LIVE_INFO)
        } ?: throw IllegalArgumentException("liveInfo is null")
    }
    private val mScreenshotStrategy by lazy {
        arguments?.getParcelable<ScreenshotStrategyVo>(LiveConst.Params.SCREENSHOT_STRATEGY)
    }

    private val mSessionFragment by lazy {
        MessageSessionDialogFragment().apply {
            arguments = bundleOf(
                LiveConst.Params.NEED_CLICK_AVATAR to false
            )
        }
    }
    private val mGiftGivingAnimationProxy by lazy {
        GiftGivingAnimationProxy(mViewModel, this)
    }
    private val mBigBrotherEntersTheArenaProxy by lazy {
        BigBrotherEntersTheArenaProxy(mBinding.gifta, this)
    }

    private var mEmojiList: List<LiveEmojiResp>? = null

    private var mSubsidy: LiveSubsidyIndicatorResp? = null

    private val mPartyImProxy by lazy {
        PartyImProxy.create(mLiveInfo.liveId, mLiveInfo.userId, mPartyImListener, this)
    }
    private var mPauseLiving: Boolean = false
    private var mStopLive: Boolean = false

    //被禁言的人
    private val mBanMessageUser = mutableListOf<Long>()

    //房管
    private val mAdministrators = mutableListOf<Long>()

    /**
     * 进场动效
     */
    private val mEntryScreenAnimationProxy by lazy {
        EntryScreenAnimationProxy(
            requireActivity(),
            mBinding.entryFloatingScreen,
            mBinding.entryScreen,
            viewLifecycleOwner
        )
    }
    private val mLivePublicProxy by lazy {
        LivePublicProxy(requireContext(), mViewModel)
    }

    //礼物代理
    private val mGiftProxy by lazy {
        GiftAnimationProxy(this, requireActivity(), mBinding.llGift, mLiveInfo.nickname).apply {
            //礼物队列点击头像
            setOnHeadOnClickListener {
                showPartyUserProfilePopup(it, true)
            }
        }
    }

    //礼物轮盘代理
    private val mGiftDialogProxy by lazy {
        GiftDialogProxy(requireContext(), mViewModel, mLiveInfo, mBinding.icRun, false)
            .apply {
                setOnUserProfileClickListener {//礼物轮盘点击查看礼物
                    showPartyUserProfilePopup(it, true)
                }
            }
    }
    private var lastBackground: String? = null //最后设置的背景

    private var mRoomFinishCallback: OnRoomFinishCallback? = null

    /**
     * =============================Im消息回调===========================
     */
    private val mPartyImListener = object : PartyImListener {
        override fun closeRoomMessage(da: SendLiveCloseMessage) {
            onStopLive()
        }

        override fun variableUpdate(variable: RoomVariable) {
            val liveInfo = mLiveInfo
            LiveUtils.fillLiveInfo(liveInfo, variable)
            SeatBeanUtil.getSeatId(variable.name)?.let {
                mBinding.partySeat.setUpdateDateSeat(it, liveInfo)
            }
            when (variable.name) {
                "showGainCoins" -> {
                    mBinding.contributionView.showGainCoins((mLiveInfo.showGainCoins?.formatNumberWithK()) ?: "0")
                }

                "banMessageUser" -> {
                    upDataBanMessage(liveInfo)
                }

                "administrator" -> {
                    upDataAdministrator(liveInfo)
                }

                "background" -> {
                    val background = liveInfo.background
                    if (background.isNullOrEmpty()) {
                        lastBackground = background
                        // 如果背景为空，设置默认背景图像，并调整可见性
                        mBinding.bgImg.setImageResource(drawable.party_video_bg)
                        mBinding.bgImg.visibility = View.VISIBLE
                        mBinding.bgPag.visibility = View.GONE
                        mBinding.bgPag.stop()
                    } else if (background != lastBackground) {
                        lastBackground = background
                        // 如果背景不为空且与上一个背景不同，设置新背景
                        setBackground(background)
                    }
                }
                "roomTheme" -> {
                    setSkinUi()
                }
            }
        }

        override fun userCountChange(count: Int) {
        }

        override fun publicMessage(sendLiveMessage: SendLiveMessage) {
            if (sendLiveMessage.type in ImLiveManager.publicTypes && sendLiveMessage.businessId == mLiveInfo.liveId) {
                mBinding.vMessage.addMessage(sendLiveMessage)
                if (sendLiveMessage.type == LIVE_PUBLIC_SCREEN) {
                    val ext = sendLiveMessage.ext as? MessageUserExtBean?
                    if (ext?.type == 1) { //发送的弹幕消息
                        mBinding.barrageView.addMessage(sendLiveMessage)
                    }
                }
            }

            //其他消息处理
            when (sendLiveMessage.type) {
                //发送公屏消息
                LIVE_SEND_GIFT, LUCKY_BACKPACK_GIFT -> {
                    mGiftGivingAnimationProxy.sendGiftEffect(
                        requireContext(),
                        sendLiveMessage,
                        mBinding.partySeat.getSeatData()
                    )
                    mGiftProxy.addAnimation(sendLiveMessage)
                    val ext = sendLiveMessage.ext as MessageUserExtBean
                    val payload = sendLiveMessage.payload as InviteGiftPayloadBean
                    payload.gift.animation?.let { mBinding.widgetGift.setGift(payload) }

                    val isWinning = payload.reward != null && payload.reward.times > 0
                    if (isWinning && UserManager.getUserId() == ext.user.userId) {
                        if (sendLiveMessage.type != LUCKY_BACKPACK_GIFT) {
                            GlobalDialogManager.showUserWinning(requireContext(), payload)
                        } else {
                            GlobalDialogManager.showBackPackUserWinning(requireContext(), payload)
                        }
                    }
                }

                //警告消息
                LIVE_WARN_MESSAGE -> {
                    mLivePublicProxy.onPublicMessage(sendLiveMessage)
                }

                //新主播补贴消息
                LIVE_NEW_ANCHOR -> {
                    val payload = sendLiveMessage.payload as NewAnchorSubsidyPayloadBean
                    GlobalDialogManager.showNewLiveAnchor(requireContext(), payload)
                }
                //emoji消息
                LIVE_PARTY_EMOJI -> {
                    mBinding.partySeat.showUserEmoji(sendLiveMessage)
                }
                //大哥进场
                BIG_BROTHER_ENTERS_ROOM -> {
                    mBigBrotherEntersTheArenaProxy.addData(sendLiveMessage)
                }
                //神灯进度90%
                LIVE_MAGIC_LAMP_90 -> {
                    mBinding.widgetRoomBanner.upDataMagicLamp()
                }
                //神灯开奖
                LIVE_MAGIC_LAMP_OPEN -> {
                    val payload = sendLiveMessage.payload as MagicLampCountDownBean
                    mBinding.widgetRoomBanner.upDataMagicLamp()
                    mBinding.widgetMagicLamp.addMagicLampPag(payload)
                }
            }
        }

        override fun liveEvent(command: String, argument: DataArgument) {
            when (command) {
                SFSEvent.USER_ENTER_ROOM -> {
                    val user = argument.getUser()
                    if (user == null || user.name == UserManager.getUserId().toString()) {
                        return
                    }
                    argument.getUser()?.parseVariables<LiveEnterBean>()?.let {
                        mEntryScreenAnimationProxy.addEntryScreenOtherUser(it) {
                            mBinding.vEnter.addEnterBean(it)
                        }
                    }
                }

                SFSEvent.USER_EXIT_ROOM -> {
                    val user = argument.getUser()
                    if (user == null || user.name == UserManager.getUserId().toString()) {
                        return
                    }
                    mEntryScreenAnimationProxy.removeEntryScreen(user.name.toLong())

                }
                //如果是加入则刷新直播间的信息
                SFSEvent.ROOM_JOIN -> {
                    argument.getRoom()?.also { room ->
                        room.variables.forEach {
                            variableUpdate(it)
                        }
                    }
                }
            }
        }

        override fun floatingMessage(message: SendLiveFloatingMessage) {
            mBinding.widgetFloat.addFloatView(message)
        }

        override fun noticeMessage(message: SendLiveNoticeMessage) {
            super.noticeMessage(message)
            val payload = message.payload ?: return
            val fromJson = JsonUtils.fromJson<LiveNoticePayloadBean>(payload)
            //如果是pag 就判断是否下载过了
            if (fromJson?.titleImageType == LiveConst.NoticeImageType.PAG) {
                val path =
                    FileUtils.getFilePath(FileUtils.getPagFile(), message.titleImage)
                if (File(path).exists()) {
                    GlobalDialogManager.showLiveNotice(requireContext(), message)
                } else {
                    mViewModel.downLoadPag(message)
                }
            } else {
                GlobalDialogManager.showLiveNotice(requireContext(), message)
            }

        }
    }

    /**
     * 底部点击
     */
    private val mBottomBuilder by lazy {
        PartyBottomView.Builder()
            .setShowGameButton(!GameUtils.getLiveCacheGameList().isNullOrEmpty())
            .setShowMessageButton(true)
            .setShowSettingButton(true)
            .setShowSendrButton(true)
            .setShowGiftButton(true)
            .setSendrClickBack {
                mBinding.vEdit.showKeyboard()
            }
            .setEmojiClickBack {
                showInteractionEmojiPopup()
            }
            .setGameClickBack {
                showGameList()
            }
            .setMessageClickBack {
                showChatMessage()
            }
            .setSettingClickBack {
                showRoomManagementPopup()
            }
            .setMikeStateBack {
                mViewModel.siteMicSwitch(mLiveInfo.userId, it == 1)
            }
            .setGiftClickBack {
                mGiftDialogProxy.showGiftPopup(seatList = mBinding.partySeat.getSeatData())
            }
    }

    private fun initImmersionBar() {
        ImmersionBar.with(this)
            .transparentBar()
            .titleBarMarginTop(mBinding.vHeader)
            .init()

        NavigationBarUtils.setNavigationHeight(mBinding.vHeader)
        NavigationBarUtils.setNavigationHeight(mBinding.bottom)
    }

    override fun initView(savedInstanceState: Bundle?) {
        initImmersionBar()
        EventBus.getDefault().register(this)
        initObserve()
        initListener()

        mGiftGivingAnimationProxy.initSeatViewAddr(
            mBinding.gifta, 0, 14.autoDp,
            Pair("1", mBinding.partySeat.mBinding.seat1),
            Pair("2", mBinding.partySeat.mBinding.seat2),
            Pair("3", mBinding.partySeat.mBinding.seat3),
            Pair("4", mBinding.partySeat.mBinding.seat4),
            Pair("5", mBinding.partySeat.mBinding.seat5),
            Pair("6", mBinding.partySeat.mBinding.seat6),
            Pair("7", mBinding.partySeat.mBinding.seat7),
            Pair("8", mBinding.partySeat.mBinding.seat8),
            Pair("9", mBinding.partySeat.mBinding.seat9),
        )

        mBinding.apply {
            vHeader.initData(pageType, mLiveInfo, 1)
            vMessage.initData(pageType, mLiveInfo)
            vEdit.initData(mLiveInfo)
            bottom.initialize(mBottomBuilder, mViewModel)
            contributionView.showGainCoins(mLiveInfo.showGainCoins?.formatNumberWithK() ?: "0")
            partySeat.observe(this@PartyVideoAnchorFragment)
            mBinding.widgetRoomBanner.initBannerData(lifecycle, mViewModel, mLiveInfo.liveId, mLiveInfo.userId)
            CommonCache.getMagicLampList().forEach { widgetMagicLamp.addMagicLampPag(it) }
        }
        mBinding.partySeat.setInitJoinData(mLiveInfo)

        mPartyImProxy
        mViewModel.getSubsidy()
        //适配小屏幕手机
        if (ScreenUtils.getScreenHeight() < 2000) {
            val lp = mBinding.vMessage.layoutParams as ViewGroup.MarginLayoutParams
            lp.height = 220.dp
            mBinding.vMessage.layoutParams = lp
        }

        upDataBanMessage(mLiveInfo)
        upDataAdministrator(mLiveInfo)

        mViewModel.openClearTimeJob()

        lastBackground = mLiveInfo.background
        lastBackground?.let {
            setBackground(it)
        }
        mBinding.actMarquee.getActivitiesScroll(mViewModel, mLiveInfo.userId)
        setSkinUi()
    }

    private fun setBackground(background: String) {
        val cleanUrl = background.substringBefore("?")
        if (cleanUrl.endsWith(PagConst.PAG)) {
            mBinding.bgImg.visibility = View.VISIBLE
            DownLoadFileUtil.loadPag(lifecycleScope, cleanUrl) { pagPath, localPath ->
                lastBackground?.let {
                    val nowBgPath = it.substringBefore("?")
                    if (pagPath == nowBgPath) { //相同的背景才显示
                        mBinding.bgPag.apply {
                            composition = PAGFile.Load(localPath)
                            setScaleMode(PAGScaleMode.Zoom)
                            setRepeatCount(-1)
                            if (!isPlaying) {
                                play()
                            }
                        }
                        mBinding.bgPag.visibility = View.VISIBLE
                        mBinding.bgImg.visibility = View.GONE
                    }
                }
            }
        } else {
            mBinding.bgImg.visibility = View.VISIBLE
            mBinding.bgPag.visibility = View.GONE
            mBinding.bgPag.stop()
            Glide.with(requireContext())
                .load(ImageUtils.imgPath(cleanUrl))
                .placeholder(drawable.party_video_bg)
                .into(mBinding.bgImg)
        }
    }

    override fun initData() {
        mViewModel.getGameList(mLiveInfo.liveId)
        mViewModel.getBackGiftRed()

    }

    override fun onResume() {
        super.onResume()
        onLiveResume()
    }

    private fun onLiveResume() {
        mViewModel.launchConsumeUser(mLiveInfo.liveId) //定时5秒请求一次  顶部消费列表
        mPauseLiving = false
    }

    override fun onPause() {
        super.onPause()
        mPauseLiving = true
    }

    private fun initListener() {
        mBinding.apply {
            //直播间飘屏被点击
            widgetFloat.setOnSingleClickListener { data ->
                when (data.type) {
                    LiveFloatView.GAME -> { //游戏中奖
                        GameUtils.showAndCheckGameFragment(
                            requireContext(),
                            mLiveInfo.userId,
                            data.payload
                        )
                    }
                }
            }
            //直播间用户列表
            vHeader.setOnConsumeItemClickListener { _, item ->
                showPartyUserProfilePopup(item.userId, true)
            }
            //点击主播头像
            vHeader.setOnAvatarClientListener {
                showRoomInfoPopup()
            }
            //显示头像
            vMessage.mBinding.baseMessage.setOnUserProfileClickListener {
                showPartyUserProfilePopup(it, true)
            }
            //点击在线人数
            vHeader.setOnOnlineClickListener {
                GlobalPopupManager.showOnRoomUser(
                    requireContext(), this@PartyVideoAnchorFragment, mViewModel,
                    mLiveInfo.liveId, mLiveInfo.userId,
                    LiveConst.Type.PARTY_LIVE,
                    mAdministrators,
                    onHeadClickListener = { userId ->
                        showPartyUserProfilePopup(userId, true)
                    }, onSendGiftSomeOneCallback = { userBase ->
                        userBase ?: return@showOnRoomUser
                        if (userBase.userId != UserManager.getUserId()) {
                            showChatMessage(userBase)
                        }
                    }
                )
            }
            //公屏举报
            vMessage.mBinding.baseMessage.setOnReportListener {
                if (it.ext is MessageUserExtBean) {
                    GlobalPopupManager.showReport(
                        requireContext(), it.ext.user.nickname,
                        mViewModel, it.ext.user.userId, mLiveInfo.liveId
                    )
                }
            }
            /**
             * 座位回调
             */
            partySeat.setPartySeatListener(object : PartyVideoSeatListener {
                /**
                 * 被点击
                 */
                override fun clickItem(seatId: Int, seatBean: VideoSeatBean) {
                    //有人
                    if (seatBean.userBasicVo != null) {
                        seatBean.userBasicVo?.userId?.let {
                            showPartyUserProfilePopup(it, false, seatBean)
                        }
                    } else {
                        if (seatBean.siteLock == true) {
                            showUnLockSeatPopup(seatId)
                        } else {
                            showSeatPopup(seatBean)
                        }

                    }
                }

                override fun updateOneSelfSeat(seatBean: VideoSeatBean?) {
                    if (seatBean == null || seatBean.siteMicStatus != 1) {
                        MediaProxy.closeMusic()
                    }
                    mBinding.bottom.apply {
                        if (seatBean == null) {
                            showMikeButton(false)
                            showEmojiButton(false)
                        } else {
                            setMikeState(seatBean.siteMicStatus ?: 1)
                            showMikeButton(true)
                            showEmojiButton(true)
                        }
                    }
                }

            })

            /**
             * 点击贡献榜
             */
            contributionView.setOnSingleClickListener {
                ContributionListPopup.showPop(
                    requireContext(),
                    this@PartyVideoAnchorFragment,
                    mViewModel,
                    UserManager.getUserId()
                ) {
                    mSessionFragment.show(
                        childFragmentManager,
                        MessageSessionDialogFragment.FRAGMENT_TAG
                    )
                    childFragmentManager.showNewDialogFragment(
                        MessageSingleDialogFragment(
                            it.user.userId,
                            it.user.avatar,
                            it.user.avatarFrame,
                            it.user.chatBubble,
                            false
                        ), MessageSessionFragment.FRAGMENT_TAG
                    )
                }
            }
            widgetRoomBanner.setMagicLampListener {
                mLiveInfo.let { info ->
                    MagicLampPopup.show(this@PartyVideoAnchorFragment, mViewModel, info.userId, false) {
                        mGiftDialogProxy.showGiftPopup(seatList = mBinding.partySeat.getSeatData())
                    }
                }

            }
            barrageView.addReportCallBack {
                GlobalPopupManager.showReport(
                    requireContext(),
                    it.nickname,
                    mViewModel,
                    it.userId,
                    it.userId
                )
            }
        }

    }

    private fun initObserve() {
        AppUtils.registerAppStatusChangedListener(onAppStatusChangedListener)

        mViewModel.clearTimeLiveData.observe(this) { _ ->
            mGiftGivingAnimationProxy.clearOverTimeQueue()
        }
        //发送公屏消息
        mBinding.vEdit.setOnSendPartyMessageListener(object : OnSendPartyMessageListener {
            override fun onSendPublicMessage(message: LivePublicScreenMessage) {
                mViewModel.sendPublicMessage(message)
            }

            override fun onBarrageWhat() {
                VipBarrageWhatPopup.showPop(requireContext(), true) {
                    Router.instance.setPath(RoutePath.VIP_CENTER_ACTIVITY)
                        .withInt("page", 0)
                        .withInt("level", 6)
                        .navigation(requireContext())
                }
            }
        })
        //关闭直播监听
        mViewModel.stopLiveLiveData.observe(this) { resultState ->
            parseState(resultState, {
                Router.builder(RoutePath.VOICE_END_ACTIVITY)
                    .withAny(LiveConst.Params.LIVE_END_INFO, it)
                    .withInt("liveType", LiveConst.Type.PARTY_LIVE)
                    .navigation(requireActivity())
            })
            mRoomFinishCallback?.onRoomFinishCallback()
        }
        //点击隐藏edit
        ViewUtils.registerTouchDown(mBinding.widgetGift) {
            mBinding.vEdit.hideKeyboard()
        }
        //获取emoji列表
        mViewModel.mEmojiListLiveData.observe(this) { resultState ->
            parseState(resultState, {
                mEmojiList = it
                showInteractionEmojiPopup()
            })
        }
        //直播获取顶部消费列表
        mViewModel.liveConsumeLiveData.observe(this) { (liveId, it) ->
            if (mLiveInfo.liveId == liveId) {
                mBinding.vHeader.updateConsumeList(it)
                mBinding.widgetRoomBanner.upDataMagicLamp()
            }
        }
        //活动滚动信息刷新
        mViewModel.activitiesScrollLiveData.observe(this) {
            mLiveInfo.let { info ->
                mBinding.actMarquee.getActivitiesScroll(mViewModel, info.userId)
            }
        }
        //pag下载
        mViewModel.mDownLoadLiveData.observe(this) {
            GlobalDialogManager.showLiveNotice(requireContext(), it)
        }

        //获取游戏列表
        mViewModel.gameLiveData.observe(this) { resultState ->
            parseState(resultState, {
                mBinding.bottom.showGameButton(it.isNotEmpty())
                GameUtils.setLiveCacheGameList(it)
                mViewModel.gameRank(mLiveInfo.liveId)
            })
        }
        //恢复直播间失败
        mViewModel.recoverFailureLiveData.observe(this) {
            onStopLive()
        }
        mViewModel.mSubsidyLiveData.observe(this) { resultState ->
            parseState(resultState, {
                if (mSubsidy == null) {
                    mSubsidy = it
                } else {
                    mSubsidy = it
                    if (it.show) {
                        XPopup.Builder(requireContext())
                            .isDestroyOnDismiss(true)
                            .asCustom(AwardProgressDialog(requireContext(), it))
                            .show()
                    }
                }
            })
        }
        //位置上下锁
        mViewModel.siteLockData.observe(this) { resultState ->
            parseState(resultState, {
                if (it.lock) {
                    ToastGravity.showGravity(R.string.locked_successfully)
                } else {
                    ToastGravity.showGravity(R.string.unlocking_successful)
                }

            }) {
                ToastGravity.showGravity(R.string.operation_failed)
            }
        }
        //截图
        LiveUtils.resolveScreenshotStrategy(pageType, mScreenshotStrategy)?.also {
            mViewModel.launchScreenshot(mLiveInfo.liveId, mLiveInfo.startTime, it)
        }
        mViewModel.mBackGiftRedData.observe(this) { resultState ->
            parseState(resultState, {
                mBinding.bottom.setBackPackRed(if (it) View.VISIBLE else View.GONE)
            })
        }
        mViewModel.exitLiveLiveData.observe(this) {
            mRoomFinishCallback?.onRoomFinishCallback()
        }
        //任务红点
        TaskRedProxy.observe(this, object : TaskRedListener {
            override fun updateRed(isRed: Boolean) {
                mBinding.bottom.setSettingRed(if (isRed) View.VISIBLE else View.GONE)
            }
        })
        mViewModel.mLampLotteryLiveData.observe(this) { resultState ->
            parseState(resultState, {
                MagicLampWinRewardPopup.show(requireContext(), it)
            }) {
                ToastGravity.showGravity(it.errorMsg)
            }
        }
        mBinding.widgetMagicLamp.openMagicLampCallBack {
            mLiveInfo.userId.let { userId ->
                mViewModel.lampLottery(userId, it.index.toLong())
            }
        }
        //路由监听
        RouterControlManager.observeListener(this) { key, ext ->
            withLoaded {
                when (key) {
                    RouterControlManager.ROUTER_ROOMGAME -> { //打开幸运游戏列表
                        val gameId = ext["gameId"]?.toLongOrNull()
                        if (gameId == null) {
                            showGameList()
                        } else {
                            val gameVo = GameUtils.getLiveCacheGameList()
                                ?.asSequence()
                                ?.flatMap { it.list.asSequence() }
                                ?.find { it.gameID == gameId }
                            if (gameVo != null) {
                                val roomId = mLiveInfo.userId.toString()
                                GameUtils.showGameFragment(requireContext(), gameVo, roomId = roomId)
                            } else {
                                showGameList()
                            }
                        }
                    }

                    RouterControlManager.ROUTER_GIFT -> { //礼物盘拉起
                        val giftType = ext["giftType"]?.toIntOrNull()
                        mGiftDialogProxy.showGiftPopup(
                            seatList = mBinding.partySeat.getSeatData(),
                            giftType = giftType
                        )
                    }
                }
            }
        }
        //更新弹幕信息
        mViewModel.barrageNumberLiveData.observe(this) { resultState ->
            parseState(resultState, {
                mBinding.vEdit.upBarrage(it)
            })
        }
    }

    private val onAppStatusChangedListener = object : Utils.OnAppStatusChangedListener {
        override fun onForeground(activity: Activity?) {
            mViewModel.stopKillActivityTimeout()
        }

        override fun onBackground(activity: Activity?) {
            mViewModel.killActivityTimeout(maxBackgroundTime)
        }
    }

    private fun showGameList() {
        val roomId = (mLiveInfo.userId ?: "").toString()
        GameListPopup.show(requireContext(), GameUtils.getLiveCacheGameList(), roomId)
    }

    /**
     * 显示房间信息
     */
    private fun showRoomInfoPopup() {
        RoomInfoAnchorPopup.show(
            this,
            mLiveInfo.liveId,
            mLiveInfo.userId,
            mLiveInfo.roomId ?: "",
            mLiveInfo.vipLevel,
            mLiveInfo.roomTheme,
            {
                showPartyUserProfilePopup(it, true)
            },
            {
                mBinding.vHeader.updateRoomName(it)
            })
    }

    /**
     * 显示资料卡片
     * search 是否查找座位上的人信息
     */
    private fun showPartyUserProfilePopup(
        userId: Long,
        search: Boolean = false,
        seatBean: BaseSeatBean? = null,
    ) {
        val mutableSeatBean =
            seatBean ?: if (search) mBinding.partySeat.getSeatBeanByUserId(userId) else null
        GlobalPopupManager.showPartyAnchorUserProfilePopup(
            requireContext(),
            this,
            mViewModel,
            userId,
            UserConst.From.LIVE,
            mLiveInfo.liveId,
            mutableSeatBean,
            mBanMessageUser,
            onLeaveSeatClickListener = {
                mViewModel.liveSiteDown(mLiveInfo.userId)
            },
            onGiftClickListener = {
                //点击送礼
                mGiftDialogProxy.showGiftPopup(it.toUserBasicVo())
            }, onFollowerClickListener = {

            }, onMessageClickListener = {
                showChatMessage(it.toUserBasicVo())
            }, onSelectMoreCardListener = { infoUser ->
                showSelectMoreCard(infoUser)
            })

    }

    private fun showSelectMoreCard(infoUserResp: InfoOtherResp) {
        val mutableSeatBean = mBinding.partySeat.getSeatBeanByUserId(infoUserResp.userId)
        GlobalPopupManager.showSelectMoreCard(
            requireContext(),
            this,
            mViewModel,
            infoUserResp,
            mutableSeatBean,
            mBanMessageUser,
            mAdministrators,
            mLiveInfo.liveId,
            mLiveInfo.userId,
            true,
            onInviteOrKickSiteListener = {
                if (it) {
                    mViewModel.partyInviteSite(infoUserResp.userId, null, mLiveInfo.liveId)
                } else {
                    //踢下座位
                    mViewModel.siteKick(infoUserResp.userId, mLiveInfo.userId)
                }
            }, onKickRoomListener = {
                //踢出房间
                mViewModel.kickUser(infoUserResp.userId, mLiveInfo.userId, mLiveInfo.roomId)
            }, onAtClickListener = {
                mBinding.vEdit.atUser(infoUserResp.userId, infoUserResp.nickname)
            }
        )
    }

    /**
     * 显示座位管理
     */
    private fun showSeatPopup(seatBean: BaseSeatBean) {
        XPopup.Builder(requireContext())
            .isViewMode(true)
            .hasShadowBg(true)
            .isDestroyOnDismiss(true)
            .asCustom(
                SeatSettingPopup(
                    requireContext(), seatBean, mViewModel, UserManager.getUserId(), mLiveInfo.liveId
                ) {
                    showSitePop(seatBean)
                }
            )
            .show()
    }

    /**
     * 上麦
     */
    private fun showSitePop(seatBean: BaseSeatBean) {
        //麦位被锁不响应
        if (seatBean.siteLock != true) {
            StartLiveProxy.permissionAudio(requireContext(), {
                upSeat(false, seatBean.seatId)
            })
        }
    }

    private fun upSeat(isInvite: Boolean, seatId: Int?) {
        StartLiveProxy.permissionAudio(requireContext(), {
            mViewModel.liveSiteUp(mLiveInfo.userId, isInvite, seatId)
        })
    }

    /**
     * 显示Emoji管理
     */
    private fun showInteractionEmojiPopup() {
        if (mEmojiList == null) {
            mViewModel.emojiList()
            return
        }
        mEmojiList?.let {
            XPopupUtils.showViewPopup(
                InteractionEmojiPopup(requireContext(), it, mViewModel, {
                    mLiveInfo.liveId.let { it1 -> mViewModel.sendEmoji(it.id, it1) }
                }) {
                    mEmojiList = null
                }
            )
        }

    }

    /**
     * 显示解锁座位弹窗
     */
    private fun showUnLockSeatPopup(seatId: Int) {
        XPopup.Builder(requireContext())
            .isViewMode(true)
            .hasShadowBg(false)
            .moveUpToKeyboard(false)
            .isDestroyOnDismiss(true)
            .asCustom(UnLockSeatPopup(requireContext()) {
                mViewModel.siteLock(seatId, false, mLiveInfo.userId)
            })
            .show()
    }

    /**
     * 显示房间管理RoomManagement
     */
    private fun showRoomManagementPopup() {
        XPopup.Builder(requireContext())
            .isViewMode(true)
            .hasShadowBg(false)
            .moveUpToKeyboard(false)
            .isDestroyOnDismiss(true)
            .asCustom(
                RoomManagementPopup(requireContext(), true,
                    2,
                    mBinding.partySeat.getMeSeatBean() != null,
                    mBinding.partySeat.getIsOpenCamera(),
                    mLiveInfo,
                    mViewModel, mBinding.widgetGift.getIsOpenGift(), mBinding.widgetGift.getIsOpenSound(),
                    onKeyboardStateListener = {
                        mBinding.vEdit.setKeyboardListerState(it)
                    }, onCloseBack = {
                        onStopLive(false)
                    }, onBeauty = {
                        XPopupUtils.showViewPopup(
                            BeautyPopup(requireContext()) { item, type ->
                                FaceManager.setBeautyEvent(item, type)
                            }.apply {
                                autoFragmentHide(this@PartyVideoAnchorFragment)
                            },
                        )
                    }, onSwitchCamera = {
                        mBinding.partySeat.onSwitchCamera()
                    }, onOpenGiftAnimation = {
                        mBinding.widgetGift.setIsOpenGiftAnimation(it)
                        mBinding.widgetMagicLamp.setIsOpenGiftAnimation(it)
                    }, onOpenGiftSound = {
                        mBinding.widgetGift.setIsOpenSound(it)
                    }, music = {
                        MusicPopup.show(this@PartyVideoAnchorFragment) {
                            upSeat(false, null)
                        }
                    }, onExitTherRoom = {
                        exitRoom()
                    }, onUserClick = {
                        showPartyUserProfilePopup(it, true)
                    }, onInvitationFriend = {
                        val fragmentManager = childFragmentManager
                        RoomInvitationFragmentDialog().apply {
                            arguments = bundleOf("liveId" to mLiveInfo.liveId)
                        }.show(
                            fragmentManager,
                            "RoomInvitationFragmentDialog"
                        )

                    })
            )
            .show()
    }

    override fun onNetwork(isNetwork: Boolean, isConnected: Boolean) {
        if (mPauseLiving) {
            return
        }
        withLoaded {
            //如果上次是断开连接，这次连接上了，需要重连
            if (isConnected) {
                onRecoverLive()
            }
        }
    }

    /**
     * 调用重连
     */
    private fun onRecoverLive() {
        withLoaded {
            mViewModel.recoverLive(mLiveInfo.roomId)
        }
    }

    /**
     * 退出直播间
     */
    private fun exitRoom() {
        mViewModel.exitLive(mLiveInfo.userId, mLiveInfo.roomId)
    }

    fun setOnRoomFinishCallback(l: OnRoomFinishCallback) {
        mRoomFinishCallback = l
    }

    //停止直播
    private fun onStopLive(needLoading: Boolean = false) {
        if (mStopLive) {
            return
        }
        mViewModel.stopLive(mLiveInfo.liveId, needLoading, mLiveInfo.roomId)
        mStopLive = true
    }

    //重置直播间UI
    private fun resetLive() {
        mBinding.vEdit.reset()
    }

    override fun onBackPressed(): Boolean {
        if (!isCreated() || activity?.isFinishing != false) {
            return true
        }

        LiveHangUpDialog.showDialog(
            requireContext(),
            null,
            mLiveInfo,
            null,
            true
        ) {
            exitRoom()
        }

        return true
    }

    override fun onDestroyView() {
        resetLive()
        mBinding.partySeat.destroyView()
        mViewModel.stopClearTimeJob()
        mViewModel.cancelGameRankJob()
        super.onDestroyView()
    }

    override fun onDestroy() {
        super.onDestroy()
        EventBus.getDefault().unregister(this)
        AppUtils.unregisterAppStatusChangedListener(onAppStatusChangedListener)
    }

    /**
     * 展示消息列表
     */
    private fun showChatMessage(userBase: UserBasicVo? = null) {
        if (userBase != null) {
            childFragmentManager.showNewDialogFragment(
                MessageSingleDialogFragment(
                    userBase.userId,
                    userBase.avatar,
                    userBase.avatarFrame,
                    userBase.chatBubble,
                    nestedPage = false,
                    singlePage = true,
                    needClickAvatar = false
                ), MessageSessionFragment.FRAGMENT_TAG
            )
        } else {
            mSessionFragment.show(
                childFragmentManager,
                MessageSessionDialogFragment.FRAGMENT_TAG
            )
        }
    }

    /**
     * 更新禁止发言用户
     */
    private fun upDataBanMessage(liveInfo: LiveRoomInfo) {
        mBanMessageUser.clear()
        liveInfo.banMessageUser?.let { banMessageUserJson ->
            val data: List<Long>? = JsonUtils.fromJson(banMessageUserJson)
            data?.let {
                mBanMessageUser.addAll(it)
            }
        }
    }

    /**
     * 更新管理员
     */
    private fun upDataAdministrator(liveInfo: LiveRoomInfo) {
        mAdministrators.clear()
        liveInfo.administrator?.let {
            val data: List<Long>? = JsonUtils.fromJson(it)
            if (data?.isNotEmpty() != null) {
                mBinding.partySeat.upDataUserPosition(data)
                mAdministrators.addAll(data)
            }
        }
    }

    /**
     * 在后台计时到
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onBackGroundEvent(event: BackgroundEvent) {
        exitRoom()
    }

    /**
     * 更新皮肤
     */
    private fun setSkinUi() {
        val themeData = AppConfigManager.getUserTheme(mLiveInfo.roomTheme)
        mBinding.vHeader.setTheme(themeData)
        mBinding.bottom.setTheme(themeData)
        mBinding.partySeat.setTheme(themeData)
    }

    companion object {

        private const val pageType = LiveConst.Page.VIDEO_PARTY_ANCHOR

        private const val maxBackgroundTime = 30000L //主播在后台停留关闭直播时长

    }

}